// @preview-file on clear
import { Node,Sprite, Director, View,Camera2D,tolua,TypeName,TextureFilter,TextureWrap,Rect,Vec2,Ease,Move,Label,cycle, sleep,AudioBus,Audio,AudioSource,wait } from 'Dora';

const GameRoot = Node();
GameRoot.renderGroup = true;

const DesignSceneHeight = 512;
const DesignSceneWidth = 512;

const updateViewSize = () => {
	const camera = tolua.cast(Director.currentCamera, TypeName.Camera2D);
	if (camera) {
		camera.zoom = math.min(View.size.width / DesignSceneWidth, View.size.height / DesignSceneHeight)
	}
};

updateViewSize();

Director.entry.onAppChange(settingName => {
	if (settingName === 'Size') {
		updateViewSize();
	}
});

const walksound = AudioSource("sfx/walk.wav",false);
if(walksound!=null)walksound.looping = false;
const boxsound = AudioSource("sfx/pushBox.wav",false);
if(boxsound!=null)boxsound.looping = false;
const divesound = AudioSource("sfx/pushBoxdive.wav",false);
if(divesound!=null)divesound.looping = false;
const changesound = AudioSource("sfx/change.wav",false);
if(changesound!=null)changesound.looping = false;
const music = AudioSource("music/Snowfall (Looped ver.).ogg",false);
if(music!=null){
	music.looping = true;
	music.setLoopPoint(0);
}

const background = Sprite("Image/background.png");
if(background !== null){
	background.uwrap = TextureWrap.Mirror;
	background.vwrap = TextureWrap.Mirror;
	background.filter = TextureFilter.Point;
	const scale = math.max(View.size.width / background.size.width, View.size.height / background.size.height);
	const ractSize = math.max(scale*background.size.width, scale*background.size.width);
	
	background.textureRect = Rect(0,0,ractSize,ractSize);
	background.scaleX = background.scaleY = scale;
	background.renderOrder = 0;
	GameRoot.addChild(background);
}

const blackscene = Sprite("Image/black.png");
if(blackscene !== null){
	blackscene.renderOrder = 99;
	GameRoot.addChild(blackscene);
}

const text_array:string[] = ["有时，我觉得自己生活在一座无法命名的小岛上。\n它并不遥远，却总让我感到隔着一道难以跨越的水面。","岛上散落着许多箱子——\n沉甸甸的疲惫，未被理解的沉默,\n还有那些不知该放在哪的情绪和愿望。\n它们像是负担，\n却又是我唯一能触碰、能移动的东西。","于是我开始推。\n把它们慢慢推向水面，\n让每一次尝试都在浪花上留下微小的痕迹。\n有的沉下去，有的漂走，\n也有一些落在我脚下，\n悄悄成为一段能向前迈步的桥。","也许，这就是与罕见病共存的日常：\n不确定，不稳固，\n但仍努力为自己架起一点点前进的可能。","哪怕桥很细、很摇晃、很脆弱——\n只要它能承住我迈出的那一小步，\n我就会继续前行。","因为我相信，\n只要不停下，总会到达新的地方。","WASD控制移动\nR重新开始\nMade By OpenMind Team"];

let start = false;

const test = Label("font.ttf",25);
if(test != null){
	test.text = "推箱为桥\nPush to Bridge\n\n\n按R以开始游戏";
	test.once(()=>{ 
		wait(()=>{
			return start;
		})
		let i = 0;
		cycle(20, time => {
			if(time*10>(10/7)*i&&i<=6){
				test.text = text_array[i];
				i+=1;
			}
		});
		if(blackscene !== null) GameRoot.removeChild(blackscene);
		test.text = "";
	})
}



const scene = Sprite("Image/scene.png");
if(scene !== null){
	scene.filter = TextureFilter.Point;
	scene.renderOrder = 1;
	GameRoot.addChild(scene);
}

function deepCopy2DArray(arr:number[][]) {
  return arr.map(row => [...row]);
}


class Player{
	node:any;
	posx:number;
	posy:number;
	constructor(x:number,y:number){
		this.posx = x;
		this.posy = y;
		if(!(GameRoot.getChildByTag("player"))){
			this.node = Sprite("Image/testplayer.png");
			this.node.filter = TextureFilter.Point;
			if(this.node!=null){
				this.node.position = Vec2(x*32,y*32);
				this.node.renderOrder = 9;
				GameRoot.addChild(this.node);
			}
		}
	}

	moveOneStep(dir:number){
		let targetPos:any;//1左，2右，3上，4下
		switch(dir){
			case 1:
				targetPos = Vec2((this.posx-1)*32,this.posy*32)
				break;
			case 2:
				targetPos = Vec2((this.posx+1)*32,this.posy*32)
				break;
			case 3:
				targetPos = Vec2(this.posx*32,(this.posy+1)*32)
				break;
			case 4:
				targetPos = Vec2(this.posx*32,(this.posy-1)*32)
				break;
			default:
				targetPos = Vec2(this.posx*32,this.posy*32);
				break;
		}
		const pos = Vec2(this.posx*32,this.posy*32);
		print(pos);
		this.node.perform(this.node,Move(
			0.2,
			pos,
			targetPos,
			Ease.InOutQuad
		));
		this.posx = targetPos.x/32;
		this.posy = targetPos.y/32;
	}
	setPos(x:number,y:number){
		const pos = Vec2(this.posx*32,this.posy*32);
		this.posx = x;
		this.posy = y;
		const targetPos = Vec2(this.posx*32,this.posy*32);
		this.node.perform(this.node,Move(
			0.01,
			pos,
			targetPos,
			Ease.InOutQuad
		));
		this.node.position = Vec2(x*32,y*32);
	}
}

class Box{
	node:any;
	posx:number;
	posy:number;
	isAvailable:boolean = true;
	constructor(x:number,y:number){
		this.posx = x;
		this.posy = y;
		if(!(GameRoot.getChildByTag("box"))){
			this.node = Sprite("Image/box.png");
			this.node.filter = TextureFilter.Point;
			if(this.node!=null){
				this.node.position = Vec2(x*32,y*32);
				this.node.renderOrder = 4;
				GameRoot.addChild(this.node);
			}
		}
	}

	moveOneStep(dir:number){
		let targetPos:any;//1左，2右，3上，4下
		switch(dir){
			case 1:
				targetPos = Vec2((this.posx-1)*32,this.posy*32)
				break;
			case 2:
				targetPos = Vec2((this.posx+1)*32,this.posy*32)
				break;
			case 3:
				targetPos = Vec2(this.posx*32,(this.posy+1)*32)
				break;
			case 4:
				targetPos = Vec2(this.posx*32,(this.posy-1)*32)
				break;
			default:
				targetPos = Vec2(this.posx*32,this.posy*32);
				break;
		}
		const pos = Vec2(this.posx*32,this.posy*32);
		print(pos);
		this.node.perform(this.node,Move(
			0.2,
			pos,
			targetPos,
			Ease.InOutQuad
		));
		this.posx = targetPos.x/32;
		this.posy = targetPos.y/32;
	}
	dive(){
		GameRoot.removeChild(this.node);
		this.node = Sprite("Image/boxdive.png");
		this.node.filter = TextureFilter.Point;
		if(this.node!=null){
				this.node.position = Vec2(this.posx*32,this.posy*32);
				this.node.renderOrder = 3;
				GameRoot.addChild(this.node);
		}
		this.isAvailable = false;

	}
	delete(){
		GameRoot.removeChild(this.node);
	}
}

class Wood{
	node:any;
	posx:number;
	posy:number;
	isAvailable:boolean = true;
	constructor(x:number,y:number){
		this.posx = x;
		this.posy = y;
		if(!(GameRoot.getChildByTag("wood"))){
			this.node = Sprite("Image/wood.png");
			this.node.filter = TextureFilter.Point;
			if(this.node!=null){
				this.node.position = Vec2(x*32,y*32);
				this.node.renderOrder = 4;
				GameRoot.addChild(this.node);
			}
		}
	}

	moveOneStep(dir:number){
		let targetPos:any;//1左，2右，3上，4下
		switch(dir){
			case 1:
				targetPos = Vec2((this.posx-1)*32,this.posy*32)
				break;
			case 2:
				targetPos = Vec2((this.posx+1)*32,this.posy*32)
				break;
			default:
				targetPos = Vec2(this.posx*32,this.posy*32);
				break;
		}
		const pos = Vec2(this.posx*32,this.posy*32);
		print(pos);
		this.node.perform(this.node,Move(
			0.2,
			pos,
			targetPos,
			Ease.InOutQuad
		));
		this.posx = targetPos.x/32;
		this.posy = targetPos.y/32;
	}
	dive(){
		GameRoot.removeChild(this.node);
		this.node = Sprite("Image/woodDive.png");
		this.node.filter = TextureFilter.Point;
		if(this.node!=null){
				this.node.position = Vec2(this.posx*32,this.posy*32);
				this.node.renderOrder = 3;
				GameRoot.addChild(this.node);
		}
		this.isAvailable = false;

	}
	delete(){
		GameRoot.removeChild(this.node);
	}
}

class GameManager {
	player:Player = new Player(0,0);
	box_list:Box[] = [];
	box_listLength:number = 0;
	wood_list:Wood[] = [];
	wood_listLength:number = 0;

	targetTag:number = -1;

	roomMap:number[][] =  Array.from([
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [3, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 3]
]);


	constructor(map:number[][]){
		this.roomMap= deepCopy2DArray(map);
		let count = 0;
		let count_wood = 0;
		this.box_listLength = 0;
		this.wood_listLength = 0;
		this.targetTag = -1;
		for (let i = 0; i < this.roomMap.length; i++) {
  		for (let j = 0; j < this.roomMap[i].length; j++) {
    		switch(this.roomMap[i][j]){
					case 0:
						break;
					case 1:
						this.player.setPos(j-7,i-7);
						const ground1 = Sprite("Image/ground.png");
						if(ground1!=null){
							ground1.filter = TextureFilter.Point;
							ground1.position = Vec2(j*32-224,i*32-224);
							ground1.renderOrder = 2;
							GameRoot.addChild(ground1);
							ground1.tag = "0";
						}
						break;
					case 2:
						this.box_list[count] = new Box(j-7,i-7);
						const ground2 = Sprite("Image/ground.png");
						if(ground2!=null){
							ground2.filter = TextureFilter.Point;
							ground2.position = Vec2(j*32-224,i*32-224);
							ground2.renderOrder = 2;
							GameRoot.addChild(ground2);
							ground2.tag = "0";
						}
						count+=1;
						this.box_listLength += 1;
						break;
					case 4:
						const heye = Sprite("Image/heye.png");
						if(heye!=null){
							heye.filter = TextureFilter.Point;
							heye.position = Vec2(j*32-224,i*32-224);
							heye.renderOrder = 2;
							GameRoot.addChild(heye);
							heye.tag = "0";
						}
						break;
					case 5:
						this.wood_list[count_wood] = new Wood(j-7,i-7);
						const ground3 = Sprite("Image/ground.png");
						if(ground3!=null){
							ground3.filter = TextureFilter.Point;
							ground3.position = Vec2(j*32-224,i*32-224);
							ground3.renderOrder = 2;
							GameRoot.addChild(ground3);
							ground3.tag = "0";
						}
						count_wood+=1;
						this.wood_listLength += 1;
						break;
					case 9:
						break;
					default:
						const ground = Sprite("Image/ground.png");
						if(ground!=null){
							ground.filter = TextureFilter.Point;
							ground.position = Vec2(j*32-224,i*32-224);
							ground.renderOrder = 2;
							GameRoot.addChild(ground);
							ground.tag = "0";
						}
						break;
				}
  		}
		}
	}
	posTag(x:number,y:number){
		if(x<=14&&y<=14&&x>=0&&y>=0){
			return this.roomMap[y][x];
		}
		return 0;
	}
	changeMap(map:number[][]){
		const change1 = Sprite("Image/Change1.png");
		if(change1!=null){
				change1.filter = TextureFilter.Point;
				change1.position = Vec2(0,-512);
				change1.renderOrder = 10;
				GameRoot.addChild(change1);
				change1.perform(Move(
					0.20,
					Vec2(0,-512),
					Vec2(0,512),
					Ease.InOutQuad
				));
				change1.once(()=>{
					sleep(0.2);
					GameRoot.removeChild(change1);
				});
		}
		const change2 = Sprite("Image/Change2.png");
		if(change2!=null){
				change2.filter = TextureFilter.Point;
				change2.position = Vec2(0,512);
				change2.renderOrder = 10;
				GameRoot.addChild(change2);
				change2.perform(Move(
					0.20,
					Vec2(0,512),
					Vec2(0,-512),
					Ease.InOutQuad
				));
				change2.once(()=>{
					sleep(0.2);
					GameRoot.removeChild(change2);
				});
		}
		this.roomMap = deepCopy2DArray(map);
		while(GameRoot.getChildByTag("0")!=null){
			GameRoot.removeChildByTag("0");
		}
		for (let i = 0; i < this.box_listLength; i++){
			this.box_list[i].delete();
		}
		for (let i = 0; i < this.wood_listLength; i++){
			this.wood_list[i].delete();
		}
		this.box_listLength = 0;
		this.wood_listLength = 0;
		let count = 0;
		let count_wood = 0;
		this.targetTag = -1;
		for (let i = 0; i < this.roomMap.length; i++) {
  		for (let j = 0; j < this.roomMap[i].length; j++) {
    		switch(this.roomMap[i][j]){
					case 0:
						break;
					case 1:
						this.player.setPos(j-7,i-7);
						const ground1 = Sprite("Image/ground.png");
						if(ground1!=null){
							ground1.filter = TextureFilter.Point;
							ground1.position = Vec2(j*32-224,i*32-224);
							ground1.renderOrder = 2;
							GameRoot.addChild(ground1);
							ground1.tag = "0";
						}
						break;
					case 2:
						this.box_list[count] = new Box(j-7,i-7);
						const ground2 = Sprite("Image/ground.png");
						if(ground2!=null){
							ground2.filter = TextureFilter.Point;
							ground2.position = Vec2(j*32-224,i*32-224);
							ground2.renderOrder = 2;
							GameRoot.addChild(ground2);
							ground2.tag = "0";
						}
						count+=1;
						this.box_listLength += 1;
						break;
					case 4:
						const heye = Sprite("Image/heye.png");
						if(heye!=null){
							heye.filter = TextureFilter.Point;
							heye.position = Vec2(j*32-224,i*32-224);
							heye.renderOrder = 2;
							GameRoot.addChild(heye);
							heye.tag = "0";
						}
						break;
					case 5:
						this.wood_list[count_wood] = new Wood(j-7,i-7);
						const ground3 = Sprite("Image/ground.png");
						if(ground3!=null){
							ground3.filter = TextureFilter.Point;
							ground3.position = Vec2(j*32-224,i*32-224);
							ground3.renderOrder = 2;
							GameRoot.addChild(ground3);
							ground3.tag = "0";
						}
						count_wood+=1;
						this.wood_listLength += 1;
						break;
					case 9:
						break;
					default:
						const ground = Sprite("Image/ground.png");
						if(ground!=null){
							ground.filter = TextureFilter.Point;
							ground.position = Vec2(j*32-224,i*32-224);
							ground.renderOrder = 2;
							GameRoot.addChild(ground);
							ground.tag = "0";
						}
						break;
				}
  		}
		}
		if(changesound!=null) changesound.play();
	}
	getPlayer(){
		return this.player;
	}
	player_move(dir:number){
		if(this.player!=null){
			let targetPosX = this.player.posx+7;
			let targetPosY = this.player.posy+7;
			let sourcePosX = targetPosX;
			let sourcePosY = targetPosY;
			switch(dir){
				case 1:
					targetPosX-=1;
					break;
				case 2:
					targetPosX+=1;
					break;
				case 3:
					targetPosY+=1;
					break;
				case 4:
					targetPosY-=1;
					break;
			}
			if(this.posTag(targetPosX,targetPosY) != 0){
				if(this.posTag(targetPosX,targetPosY)==2){
					let tempPosX:number = targetPosX,tempPosY:number = targetPosY;
					switch(dir){
					case 1:
						tempPosX = targetPosX-1;
						break;
					case 2:
						tempPosX = targetPosX+1;
						break;
					case 3:
						tempPosY = targetPosY+1;
						break;
					case 4:
						tempPosY = targetPosY-1;
						break;
					}
					if(this.posTag(tempPosX,tempPosY)==3){
						for(let i = 0;i<this.box_listLength;i++){
							if(this.box_list[i].posx==targetPosX-7&&this.box_list[i].posy==targetPosY-7&&this.box_list[i].isAvailable == true){
								this.roomMap[sourcePosY][sourcePosX] = this.targetTag==-1?3:this.targetTag;
								if(this.roomMap[targetPosY][targetPosX] == 4){
									this.targetTag = this.roomMap[targetPosY][targetPosX];
								}else{
									this.targetTag = 3;
								}
								this.roomMap[targetPosY][targetPosX] = 1;
								this.roomMap[tempPosY][tempPosX] = 2;
								this.player.moveOneStep(dir);
								this.box_list[i].moveOneStep(dir);
								if (boxsound != null) boxsound.play();
							}
						}
					}else if(this.posTag(tempPosX,tempPosY)==0||this.posTag(tempPosX,tempPosY)==4){
						for(let i = 0;i<this.box_listLength;i++){
							if(this.box_list[i].posx==targetPosX-7&&this.box_list[i].posy==targetPosY-7&&this.box_list[i].isAvailable == true){
								this.roomMap[sourcePosY][sourcePosX] = this.targetTag==-1?3:this.targetTag;
								if(this.roomMap[targetPosY][targetPosX] == 4){
									this.targetTag = this.roomMap[targetPosY][targetPosX];
								}else{
									this.targetTag = 3;
								}
								this.roomMap[targetPosY][targetPosX] = 1;
								this.roomMap[tempPosY][tempPosX] = 3;
								this.player.moveOneStep(dir);
								this.box_list[i].moveOneStep(dir);
								this.box_list[i].dive();
								if (divesound != null) divesound.play();
							}
						}
					}
				}else if(this.posTag(targetPosX,targetPosY)==5){
					if(dir == 3||dir == 4){
						return;
					}
					let tempPosX:number = targetPosX,tempPosY:number = targetPosY;
					switch(dir){
					case 1:
						tempPosX = targetPosX-1;
						break;
					case 2:
						tempPosX = targetPosX+1;
						break;
					}
					if(this.posTag(tempPosX,tempPosY)==3){
						for(let i = 0;i<this.wood_listLength;i++){
							if(this.wood_list[i].posx==targetPosX-7&&this.wood_list[i].posy==targetPosY-7&&this.wood_list[i].isAvailable == true){
								this.roomMap[sourcePosY][sourcePosX] = this.targetTag==-1?3:this.targetTag;
								if(this.roomMap[targetPosY][targetPosX] == 4){
									this.targetTag = this.roomMap[targetPosY][targetPosX];
								}else{
									this.targetTag = 3;
								}
								this.roomMap[targetPosY][targetPosX] = 1;
								this.roomMap[tempPosY][tempPosX] = 5;
								this.player.moveOneStep(dir);
								this.wood_list[i].moveOneStep(dir);
								if (boxsound != null) boxsound.play();
							}
						}
					}else if(this.posTag(tempPosX,tempPosY)==0||this.posTag(tempPosX,tempPosY)==4){
						for(let i = 0;i<this.wood_listLength;i++){
							if(this.wood_list[i].posx==targetPosX-7&&this.wood_list[i].posy==targetPosY-7&&this.wood_list[i].isAvailable == true){
								this.roomMap[sourcePosY][sourcePosX] = this.targetTag==-1?3:this.targetTag;

								if(this.roomMap[targetPosY][targetPosX] == 4){
									this.targetTag = this.roomMap[targetPosY][targetPosX];
								}else{
									this.targetTag = 3;
								}
								
								this.roomMap[targetPosY][targetPosX] = 1;
								this.roomMap[tempPosY][tempPosX] = 3;
								this.player.moveOneStep(dir);
								this.wood_list[i].moveOneStep(dir);
								this.wood_list[i].dive();
								if (divesound != null) divesound.play();
							}
						}
					}
				}else{
					this.roomMap[sourcePosY][sourcePosX] = this.targetTag==-1?3:this.targetTag;
					if(this.roomMap[targetPosY][targetPosX] == 4){
									this.targetTag = this.roomMap[targetPosY][targetPosX];
								}else{
									this.targetTag = 3;
								}
					this.roomMap[targetPosY][targetPosX] = 1;
					this.player.moveOneStep(dir);
					if (walksound != null) walksound.play();
				}
			}
		}
	}
}

let room:GameManager;
let levelCount = 0;
const levelMax = 11;
const matrix: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 1, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 2, 0, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix2: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 2, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix3: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0],
  [0, 0, 3, 3, 3, 3, 0, 0, 0, 3, 3, 0, 0, 0],
  [0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 3, 3, 1, 0],
  [0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 3, 3, 3, 0],
  [0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 2, 3, 0, 0],
  [0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 3, 3, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix4: number[][] = [
  [0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 3, 3, 3, 0],
  [0, 0, 0, 0, 0, 3, 3, 2, 2, 0, 3, 2, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 4, 3, 3, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 3, 3, 0],
  [0, 0, 0, 0, 3, 3, 2, 4, 0, 0, 3, 2, 2, 0],
  [0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 3, 3, 3, 0],
  [0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 3, 3, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 1, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix5: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0],
  [0, 0, 0, 0, 3, 3, 2, 2, 2, 3, 3, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix6: number[][] = [
  [0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 1, 3, 2, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 3, 3, 0, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 4, 0, 0, 0, 0, 0, 0],
  [0, 3, 3, 0, 0, 2, 2, 3, 0, 0, 0, 0, 0, 0],
	[0, 3, 3, 3, 3, 3, 2, 3, 0, 0, 0, 0, 0, 0],
	[0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 3, 3, 4, 4, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix7: number[][] = [
  [0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 1, 3, 2, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 3, 3, 0, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 5, 0, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 3, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 3, 3, 3, 5, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];

const matrix8: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 2, 3, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 0, 2, 5, 1, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix9: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 3, 1, 0, 2, 2, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix10: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 0],
  [0, 0, 3, 0, 2, 0, 0, 3, 0, 0, 3, 0, 0, 0],
  [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0],
  [0, 0, 3, 0, 0, 3, 0, 3, 0, 0, 3, 0, 0, 0],
  [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0],
	[0, 0, 3, 3, 0, 3, 3, 0, 3, 0, 0, 0, 0, 0],
	[0, 0, 3, 0, 3, 3, 3, 3, 0, 0, 1, 0, 0, 0],
	[0, 0, 3, 0, 3, 3, 3, 3, 3, 0, 3, 0, 0, 0],
  [0, 0, 3, 3, 3, 0, 3, 3, 0, 0, 3, 0, 0, 0],
	[0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrix11: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0],
  [0, 0, 1, 0, 3, 3, 3, 0, 3, 2, 3, 0, 0, 0],
  [0, 0, 3, 0, 3, 2, 3, 0, 0, 0, 3, 0, 0, 0],
  [0, 0, 3, 0, 3, 3, 3, 3, 3, 0, 3, 0, 0, 0],
  [0, 0, 3, 0, 3, 0, 0, 5, 3, 0, 3, 0, 0, 0],
  [0, 0, 3, 0, 3, 3, 3, 0, 3, 0, 3, 0, 0, 0],
	[0, 0, 3, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0],
	[0, 0, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 0, 0],
	[0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 4, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0],
	[0, 0, 3, 3, 3, 3, 3, 3, 3, 5, 3, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];
const matrixEnd: number[][] = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0],
  [0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0],
  [0, 0, 0, 3, 3, 3, 3, 1, 3, 3, 3, 3, 0, 0],
	[0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0],
  [0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
  [0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
	[0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
  [0, 0, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0],
  [0, 0, 0, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0],
	[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0]
];

const level:number[][][] = [matrix,matrix2,matrix3,matrix4,matrix5,matrix6,matrix7,matrix8,matrix9,matrix10,matrix11,matrixEnd];
room = new GameManager(level[levelCount]);


let leftUsed = false;
let rightUsed = false;
let upUsed = false;
let downUsed = false;

GameRoot.onKeyDown(keyName => {
	if(keyName == "A"&&leftUsed == false&&rightUsed == false&&upUsed == false&&downUsed == false){
		room.player_move(1);
		leftUsed = true;
	}
	if(keyName == "D"&&leftUsed == false&&rightUsed == false&&upUsed == false&&downUsed == false){
		room.player_move(2);
		rightUsed = true;
	}
	if(keyName == "W"&&leftUsed == false&&rightUsed == false&&upUsed == false&&downUsed == false){
		room.player_move(3);
		upUsed = true;
	}
	if(keyName == "S"&&leftUsed == false&&rightUsed == false&&upUsed == false&&downUsed == false){
		room.player_move(4);
		downUsed = true;
	}
	if(keyName == "R"){
		start = true;
		room.changeMap(level[levelCount]);
	}
});

GameRoot.onKeyUp(keyName => {
	if(keyName == "A"){
		leftUsed = false;
	}
	if(keyName == "D"){
		rightUsed = false;
	}
	if(keyName == "W"){
		upUsed = false;
	}
	if(keyName == "S"){
		downUsed = false;
	}
});




GameRoot.schedule(deltaTime => {
	if(room.getPlayer().posy == 7&&room.getPlayer().posx == 0&&levelCount<levelMax){
		levelCount+=1;
		room.changeMap(level[levelCount]);
	}
	if(levelCount == levelMax){
		if(test != null)test.text = "感谢游玩\nThanks for playing!\n\n\nspecial thanks:\nBGM:Snowfall --Kistol";
	}
	if(music!=null&&start==true&&music.playing==false){
		music.playBackground();
	}
	return false;
});